window.requestAnimFrame = (function requestAnimFrame() {
  return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    function simulation(callback) {
      window.setTimeout(callback, 1000 / 60)
    }
}())

function scrollToY(scrollTargetY = 0, speed = 2000, easing = 'easeOutSine') {
  // scrollTargetY: the target scrollY property of the window
  // speed: time in pixels per second
  // easing: easing equation to use

  const scrollY = window.scrollY

  // min time .1, max time .8 seconds
  const time = Math.max(0.1, Math.min(Math.abs(scrollY - scrollTargetY) / speed, 0.8))
  let currentTime = 0

  // easing equations from https://github.com/danro/easing-js/blob/master/easing.js
  /* eslint-disable no-restricted-properties */
  const easingEquations = {
    easeOutSine(pos) {
      return Math.sin(pos * (Math.PI / 2))
    },
    easeInOutSine(pos) {
      return (-0.5 * (Math.cos(Math.PI * pos) - 1))
    },
    easeInOutQuint(pos) {
      pos /= 0.5
      if (pos < 1) {
        return 0.5 * Math.pow(pos, 5)
      }
      return 0.5 * (Math.pow((pos - 2), 5) + 2)
    },
  }

  // add animation loop
  function tick() {
    currentTime += 1 / 60

    const p = currentTime / time
    const t = easingEquations[easing](p)

    if (p < 1) {
      window.requestAnimFrame(tick)

      window.scrollTo(0, scrollY + ((scrollTargetY - scrollY) * t))
    } else {
      window.scrollTo(0, scrollTargetY)
    }
  }

  // call it once to get started
  tick()
}

export default scrollToY
